home *** CD-ROM | disk | FTP | other *** search
- RCS_ID_C "$Id: display.c,v 1.5 1993/07/12 22:51:47 ppessi Exp $";
- /*
- * display.c --- generic display routines for niftyterm
- *
- * Copyright 1989, Chris Newman
- * All Rights Reserved
- * Permission is granted ot copy, modify, and use this as long
- * as this notice remains intact. This is a nifty program.
- *
- * DISCLAIMER: the author (and maintainer) of this program is not responsible
- * for any damage or other problems caused by it.
- *
- * $Author: ppessi $ $Revision: 1.5 $ $Date: 1993/07/12 22:51:47 $
- *
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <exec/memory.h>
- #include <clib/exec_protos.h>
- #include "nifty.h"
- #include "display.h"
- #include "dispmacros.h"
-
- #ifdef __SASC
- extern struct ExecBase *SysBase;
- #include <pragmas/exec_sysbase_pragmas.h>
- #endif
- static char AllocMemError[] = PROGNAME ": PANIC! AllocMem error\n";
-
- /* display specific routines called:
- * dsscroll(), dsinvert(), dsstyle(), dsputs()
- * idssetfont()
- */
-
- /* global display structure */
- struct nifty_display disp;
-
- /* global settings in emulate.c needed for soft reset */
- extern int vt100_yucky_wrap_mode;
- extern int ansi_LNM;
- extern int visual;
-
- /* global from main needed to set ansi_LNM correctly */
- extern int use_stdin;
-
- /* allocate the display buffers
- */
- void
- allocate_display(width,height)
- int width, height;
- {
- disp.buf = AllocMem((sizeof(char) * (width+1) * height), MEMF_CLEAR);
- disp.sbuf = (short *)AllocMem((sizeof(short) * (width+1) * height), MEMF_CLEAR);
- disp.tabstops = AllocMem((sizeof (char) * width), MEMF_CLEAR);
- disp.maxwidth = width;
- disp.maxheight = height;
- disp.bufwidth = width+1;
- if (disp.buf == NULL || disp.sbuf == NULL || disp.tabstops == NULL) {
- fputs(AllocMemError, stdout);
- exit(-1);
- }
- }
-
- /* Free up memory allocated for display */
- void
- free_display()
- {
- if(disp.buf) FreeMem(disp.buf, sizeof(char) * (disp.maxwidth + 1) * disp.maxheight);
- if(disp.sbuf) FreeMem(disp.sbuf, sizeof(short) * (disp.maxwidth + 1) * disp.maxheight);
- if(disp.tabstops) FreeMem(disp.tabstops, sizeof(char) * disp.maxwidth);
- }
-
- /* clear out the display
- */
- void
- clear_display()
- {
- register int y;
-
- for (y = 0; y < disp.maxheight; y++) {
- disp.plines[y] = disp.buf+y*disp.bufwidth;
- disp.pstyles[y] = disp.sbuf+y*disp.bufwidth;
- STYLEFLAG(y) = 0;
- LINELENST(y) = 0;
- }
- disp.curx = disp.cury = 0;
- }
-
- /* clear out the tab stops
- */
- void
- clear_tabstops()
- {
- register int i;
-
- for (i=0; i<disp.maxwidth; i++)
- disp.tabstops[i] = 0;
- }
-
- /* initialize tabstops to 8 characters
- */
- void
- init_tabstops()
- {
- register int i;
-
- for (i=0; i<disp.maxwidth; i++)
- disp.tabstops[i] = (i % 8) == 0;
- }
-
- /* reset the display
- */
- void
- reset_display(soft)
- int soft;
- {
- if(!soft) {
- clear_display();
- disp.scrolldefault = 1;
- }
- (void) dsstyle(STYLESOFF);
- disp.visual = visual;
- disp.insert = disp.origin = disp.scrolltop = disp.savex = disp.savey = 0;
- disp.scrollbot = soft ? disp.winheight - 1 : disp.maxheight;
- disp.scrollskip = disp.scrolldefault;
- disp.wrap = 1;
- init_tabstops();
- }
-
- /* move cursor to x, y
- */
- void
- dscursorto(x, y)
- int x, y;
- {
- int wflag;
-
- if (disp.origin) {
- y += disp.scrolltop;
- MAXBOUNDCK(y, disp.scrollbot);
- } else
- SLIMITCK(y, disp.winheight);
- if (disp.cury != y)
- idssetfont(disp.style, disp.cury = y);
- wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
- disp.curx = SLIMIT(x, disp.winwidth/wflag);
- }
-
- /* return size of the current window
- */
- void
- dsgetsize(x, y)
- int *x, *y;
- {
- *x = disp.winwidth;
- *y = disp.winheight;
- }
-
- /* get cursor position
- */
- void
- dsgetcursor(x, y)
- int *x, *y;
- {
- *x = disp.curx;
- *y = disp.cury;
- }
-
- /* display style changes
- */
- int
- dsstyle(style)
- int style;
- {
- switch (style) {
- case BOLD1: /* bold on */
- disp.style |= BOLD;
- break;
- case BOLD0: /* bold off */
- disp.style &= ~BOLD;
- break;
- case ITALIC1: /* italic on */
- disp.style |= ITALIC;
- break;
- case ITALIC0: /* italic off */
- disp.style &= ~ITALIC;
- break;
- case UNDERLINE1: /* underline on */
- disp.style |= UNDERLINE;
- break;
- case UNDERLINE0: /* underline off */
- disp.style &= ~UNDERLINE;
- break;
- case INVERSE1: /* inverse on */
- disp.style |= INVERSE;
- break;
- case INVERSE0: /* inverse off */
- disp.style &= ~INVERSE;
- break;
- case BLINK1:
- disp.style |= FLASH;
- break;
- case BLINK0:
- disp.style &= ~FLASH;
- break;
- case ALTERNATE1:
- disp.style |= ALTERNATE;
- break;
- case ALTERNATE0:
- disp.style &= ~ALTERNATE;
- break;
- case STYLESOFF: /* turn off all */
- disp.style = 0;
- break;
- case SAVE_STYLE: /* save the style */
- disp.savestyle = disp.style;
- break;
- case RESTORE_STYLE: /* restore the saved style */
- disp.style = disp.savestyle;
- break;
- case DWIDTH1: /* double width */
- if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == (DOUBLE1 | DOUBLE2))
- break;
- STYLEFLAG(disp.cury) |= DOUBLE1 | DOUBLE2;
- redraw_line(disp.cury);
- break;
- case DWIDTHTOP:/* double width/height top */
- if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == DOUBLE1)
- break;
- STYLEFLAG(disp.cury) &= ~DOUBLE2;
- STYLEFLAG(disp.cury) |= DOUBLE1;
- redraw_line(disp.cury);
- break;
- case DWIDTHBOT: /* double width/height bottom */
- if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == DOUBLE2)
- break;
- STYLEFLAG(disp.cury) &= ~DOUBLE1;
- STYLEFLAG(disp.cury) |= DOUBLE2;
- redraw_line(disp.cury);
- break;
- case DWIDTH0: /* single width, single height */
- if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == 0)
- break;
- STYLEFLAG(disp.cury) &= ~DOUBLE_MASK;
- redraw_line(disp.cury);
- break;
- default: /* style unavailable */
- return -1;
- }
- idssetfont(disp.style, disp.cury);
-
- return 0;
- }
-
- /* check if cursor can move down without scrolling, and move cursor if it can.
- */
- int
- dscheckdown()
- {
- return (disp.cury < disp.scrollbot ? ++disp.cury : 0);
- }
-
- /* move the cursor
- */
- void
- dscursormove(move, n)
- int move, n;
- {
- int wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
-
- if (n<1) n=1;
- switch (move) {
- case CURSOR_UP: case REVERSE_INDEX:
- disp.cury -= n;
- if (disp.cury < disp.scrolltop) {
- if (move == REVERSE_INDEX) {
- dsscroll(disp.scrolltop,disp.scrollbot - disp.scrolltop + 1,disp.cury - disp.scrolltop);
- }
- disp.cury = disp.scrolltop;
- }
- break;
-
- case CURSOR_RIGHT:
- disp.curx += n;
- SLIMITCK(disp.curx, disp.winwidth/wflag);
- break;
-
- case CURSOR_LEFT:
- disp.curx -= n;
- MINBOUNDCK(disp.curx, 0);
- break;
-
- case DOWN1_AND_SCROLL:
- {
- int scrolltop = disp.scrolltop;
- int scrollheight = disp.scrollbot - scrolltop;
- int scrollsize;
-
- if (disp.scrollskip > n)
- n = disp.scrollskip;
- if (disp.cury > disp.scrollbot) {
- scrollheight = disp.winheight;
- scrolltop = 0;
- }
- if (n > (scrollsize = (scrollheight >> 1)))
- n = scrollsize ? scrollsize : 1;
- disp.cury -= n-1;
- dsscroll(scrolltop, scrollheight + 1, n);
- }
- break;
-
- case CURSOR_DOWN: case NEXT_LINE: case INDEX:
- if (disp.cury <= disp.scrollbot && (disp.cury+=n) > disp.scrollbot) {
- if (move == CURSOR_DOWN) {
- disp.cury = disp.scrollbot;
- } else {
- dsscroll(disp.scrolltop,
- disp.scrollbot - disp.scrolltop + 1,
- disp.cury - disp.scrollbot + disp.scrollskip - 1);
- disp.cury = disp.scrollbot - disp.scrollskip + 1;
- }
- } else if (disp.cury > disp.scrollbot && (disp.cury+=n) > disp.winheight-1) {
- if (move == CURSOR_DOWN) {
- disp.cury = disp.winheight-1;
- } else {
- dsscroll(0, disp.winheight, disp.cury - disp.winheight + disp.scrollskip);
- disp.cury = disp.winheight - disp.scrollskip;
- }
- }
- if (move != NEXT_LINE)
- break;
- /* fall through */
- case BEGIN_LINE:
- disp.curx = 0;
- break;
-
- case END_LINE:
- disp.curx = disp.winwidth/wflag-1;
- break;
-
- case BOTTOM_HOME:
- disp.curx = 0;
- disp.cury = disp.winheight-1;
- break;
-
- case SAVE_CURSOR:
- disp.savex = disp.curx;
- disp.savey = disp.cury;
- (void) dsstyle(SAVE_STYLE);
- break;
-
- case RESTORE_CURSOR:
- disp.curx = disp.savex;
- disp.cury = disp.savey;
- (void) dsstyle(RESTORE_STYLE);
- break;
-
- case INSERT_LINE:
- dsscroll(disp.cury, disp.scrollbot-disp.cury+1, -n);
- break;
-
- case DELETE_LINE:
- dsscroll(disp.cury, disp.scrollbot-disp.cury+1, n);
- break;
-
- case INSERT_CHAR: {
- char insertme[MAXWIDTH];
- int temp;
-
- disp.insert++;
- insertme[SLIMIT(n,MAXWIDTH)] = '\0';
- for (temp = n; --temp >= 0; insertme[temp] = ' ');
- temp = disp.curx;
- dsputs(insertme);
- disp.curx = temp;
- disp.insert--;
- }
- break;
-
- case TAB_STOP:
- if (n > 1) {
- while (disp.curx < disp.winwidth/wflag-1 && ++disp.curx % n);
- } else {
- while (disp.curx < disp.winwidth/wflag-1 &&
- !disp.tabstops[++disp.curx]);
- }
- break;
- }
- idssetfont(disp.style, disp.cury);
- }
-
- /* miscellaneous terminal functions
- */
- void
- dsfunction(what)
- int what;
- {
- int wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
-
- switch(what) {
- case ERASETO_EOS:
- if (disp.cury < disp.winheight-1)
- dsclear(0, disp.cury+1, disp.winwidth/wflag-1, disp.winheight-1);
- /* fall through */
- case ERASETO_EOL:
- if (disp.curx < disp.winwidth/wflag-1)
- dsclear(disp.curx, disp.cury, disp.winwidth/wflag-1, disp.cury);
- break;
-
- case ERASETO_SOS:
- if (disp.cury)
- dsclear(0, 0, disp.winwidth/wflag-1, disp.cury-1);
- /* fall through */
- case ERASETO_SOL:
- if (disp.curx)
- dsclear(0, disp.cury, disp.curx, disp.cury);
- break;
-
- case ERASE_LINE:
- dsclear(0, disp.cury, disp.winwidth/wflag-1, disp.cury);
- break;
-
- case RESET_DISPLAY:
- reset_display(1);
- break;
-
- case SCROLL_UP:
- dsscroll(disp.scrolltop, disp.scrollbot - disp.scrolltop + 1, 1);
- break;
-
- case SCROLL_DOWN:
- dsscroll(disp.scrolltop, disp.scrollbot - disp.scrolltop + 1, -1);
- break;
-
- case ORIGIN_ON:
- disp.origin = 1;
- break;
-
- case ORIGIN_OFF:
- disp.origin = 0;
- break;
-
- case BLOCK_CURSOR:
- disp.visual |= CUR_BLOCK;
- break;
-
- case UNDERLINE_CURSOR:
- disp.visual &= ~CUR_BLOCK;
- break;
-
- case INVISIBLE_CURSOR:
- disp.visual |= CUR_INVISIBLE;
- break;
-
- case VISIBLE_CURSOR:
- disp.visual &= ~CUR_INVISIBLE;
- break;
-
- case WRAP_ON:
- disp.wrap = 1;
- break;
-
- case WRAP_OFF:
- disp.wrap = 0;
- break;
-
- case INSERT_ON:
- disp.insert = 1;
- break;
-
- case INSERT_OFF:
- disp.insert = 0;
- break;
-
- case SET_TAB:
- disp.tabstops[disp.curx] = 1;
- break;
-
- case CLEAR_TAB:
- disp.tabstops[disp.curx] = 0;
- break;
-
- case CLEAR_ALL_TABS:
- clear_tabstops();
- break;
- }
- idssetfont(disp.style, disp.cury);
- }
-
- /* set the scrolling region
- */
- void
- dssetscroll(top,bot)
- int top,bot;
- {
- if (top)
- top--;
- if (bot)
- bot--;
- if (bot - top < 1)
- disp.scrolltop = 0, disp.scrollbot = disp.winheight-1;
- else {
- if (top >= disp.winheight)
- top = 0;
- if (bot >= disp.winheight)
- bot = disp.winheight-1;
- disp.scrolltop = top;
- disp.scrollbot = bot;
- }
- disp.curx = 0;
- disp.cury = disp.scrolltop;
- if (disp.scrolltop || disp.scrollbot < disp.winheight-1)
- disp.scrollskip = 1;
- else
- disp.scrollskip = disp.scrolldefault;
- idssetfont(disp.style, disp.cury);
- }
-